package com.shanxia.im.service.impl;

import com.shanxia.codec.ProtocolDataBase;
import com.shanxia.codec.cmd.*;
import com.shanxia.im.sdk.server.model.IMSession;
import com.shanxia.im.service.InvokerService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class BizInvokerServiceImpl implements InvokerService {

	private static final Logger LOGGER = LoggerFactory.getLogger(BizInvokerServiceImpl.class);

	@Override
	public void invoker(IMSession session, ProtocolDataBase protocolDataBase) {

		try {
			// TODO 根据不同的充电桩账号、不通的cmd指令响应结果，调用管理平台的接口


			// 判断是否需要响应充电桩
			switch (protocolDataBase.getCmd()) {
				//) 充 电 桩 参 数 整 形 设 置/ / 查 询 应 答
				case 2:
					log.debug("接收到cmd2 参数 查询/设置 回复指令，服务器不需要回复");
					break;
				//) 充 电 桩 参 数 字 符 形 设 置/ / 查 询 应 答
				case 4:
					log.debug("接收到cmd4时间同步回复指令，服务器不需要回复");
					break;
				//) 充 电 桩 对 后 台 控 制 命 令 应 答
				case 6:
					log.debug("接收到cmd6停止充电执行结果回复指令，服务器不需要回复");
					break;
				//  充 电 桩 对 后 台 下 发 的 充 电 桩 开 启 充 电 控 制 应 答
				case 8:
					log.debug("接收到cmd8开始充电执行结果回复指令，服务器不需要回复");
					break;
				//) 充 电 桩 上 传 命 令 请 求 (预 留)
				case 10:
					log.debug("接收到cmd10指令");
					Cmd10 cmd10 = (Cmd10)protocolDataBase;
					Cmd9 cmd9 = new Cmd9();
					cmd9.copyDataFrom(cmd10);
					cmd9.setCmd(9);
					// TODO 构造返回数据
					cmd9.setCode(200);
					cmd9.setDataLen(4);
					cmd9.setData("1");
					session.write(cmd9);
					break;

				//) 充 电 桩 上 传 心 跳 包 信 息【在HeartbeatHandler中进行处理，此处忽略】
				case 102:
					log.debug("接收到cmd102【心跳指令】");
					break;
				//) 充 电 桩 状 态 信 息 包 上 传
				case 104:
					log.debug("接收到cmd104指令");
					Cmd104 cmd104 = (Cmd104)protocolDataBase;
					Cmd103 cmd103 = new Cmd103();
					cmd103.copyDataFrom(cmd104);
					cmd103.setCmd(103);
					// TODO 构造返回数据
					cmd103.setReportImmediately(false);

					session.write(cmd103);
					break;
				//) 充 电 桩 签 到 信 息 上 传【在BindHandler中进行处理，此处忽略】
				case 106:
					log.debug("接收到cmd106签到指令");
					// 签到用单独得BindHandler来接受处理
					break;
				//) 充 电 桩 告 警 信 息 上 报 (预 留)
				case 108:
					log.debug("接收到cmd108告警指令，服务器不需要回复");
					break;
				//) 充 电 桩 上 报 充 电 启 动 完 成 命 令
				case 110:
					log.debug("接收到cmd110充电启动结果回复指令");
					Cmd110 cmd110 = (Cmd110)protocolDataBase;
					Cmd109 cmd109 = new Cmd109();
					cmd109.copyDataFrom(cmd110);
					cmd109.setCmd(109);
					cmd109.setV1(0);
					cmd109.setV2(0);
					session.write(cmd109);
					break;
				//) 充 电 桩 模 块 信 息 上 报 (预 留)
				case 112:
					log.debug("接收到cmd112上报指令，服务器不需要回复");
					break;
				//) 充 电 桩 应 答 服 务 器 查 询 最 近 一 次 充 电 各 时 段 信 息
				case 114:
					log.debug("接收到cmd114回复指令，服务器不需要回复");
					break;

				//) 充 电 桩 上 报 充 电 记 录 信 息 TODO 持久化该信息到数据库中 此 条 报 文 是 充 电 费 用 的 依 据 ， 是 充 电 桩 最 重 要 的 报 文
				case 202:
					log.debug("接收到cmd202充电桩上报充电记录指令");
					Cmd202 cmd202 = (Cmd202)protocolDataBase;
					Cmd201 cmd201 = new Cmd201();
					cmd201.copyDataFrom(cmd202);
					cmd201.setCmd(201);
					// TODO 构造返回数据

					session.write(cmd201);
					break;
				// 充 电 桩 充 电 上 传 用 户 帐 户 查 询 报 文
				case 204:
					log.debug("接收到cmd204指令");
					Cmd204 cmd204 = (Cmd204)protocolDataBase;
					Cmd203 cmd203 = new Cmd203();
					cmd203.copyDataFrom(cmd204);
					cmd203.setCmd(203);
					// TODO 构造返回【测试】数据
					cmd203.setBalance(190);
					cmd203.setChargeRate(1);
					cmd203.setCarNumVerify(0);
					cmd203.setPwdVerify(0);
					cmd203.setRespCode(0);
					cmd203.setSerial("0");
					cmd203.setServiceRate(0);
					cmd203.setVin("0");

					session.write(cmd203);
					break;
				//) 充 电 桩 上 传 用 户 密 码 验 证 报 文 (预 留)
				case 206:
					log.debug("接收到cmd206指令");
					Cmd205 cmd205 = new Cmd205();
					cmd205.setCmd(205);
					// TODO 构造返回【测试】数据
					cmd205.setBalance(190);
					cmd205.setRespCode(0);
					//cmd205.setV1(0);
					//cmd205.setV2(0);
					session.write(cmd205);
					break;
				//  充 电 桩 上 报 “ 即 插 即 充 “ 启 动 充 电 请 求
				case 208:
					log.debug("接收到cmd208指令");
					Cmd208 cmd208 = new Cmd208();
					Cmd207 cmd207 = new Cmd207();
					cmd207.copyDataFrom(cmd208);
					cmd207.setCmd(207);
					// TODO 构造返回数据
					cmd207.setBalance(0);
					cmd207.setBindAccount("");
					cmd207.setCode(0);
					cmd207.setPileNum(1);
					cmd207.setPwd("123456");
					cmd207.setReason(0);
					cmd207.setSerial("100101");
					cmd207.setVin("100 VIN 001");

					session.write(cmd207);
					break;
				//) 充 电 桩 上 报 “ 即 插 即 充” ”  启 动 充 电 结 果
				case 210:
					log.debug("接收到cmd210指令");
					Cmd210 cmd210 = new Cmd210();
					Cmd209 cmd209 = new Cmd209();
					cmd209.copyDataFrom(cmd210);
					cmd209.setCmd(209);
					// TODO 构造返回数据
					cmd209.setVin("100 VIN 001");
					session.write(cmd209);
					break;


				//) 充 电 桩 上 报 BMS 信 息 (预 留)
				case 302:
					log.debug("接收到cmd302充电桩上报BMS信息指令");
					Cmd301 cmd301 = new Cmd301();
					cmd301.setCmd(301);

					session.write(cmd301);
					break;
				//) 充 电 桩 上 报 BMS 信 息 (预 留)
				case 304:
					log.debug("接收到cmd304充电桩上报BMS信息指令");
					Cmd303 cmd303 = new Cmd303();
					cmd303.copyDataFrom(protocolDataBase);
					cmd303.setCmd(303);

					session.write(cmd303);
					break;


				// 充 电 桩 上 报 历 史 的 充 电 记 录
				//1．充电桩为了保证记录能到送达后台，可能出现一条充电记录多次上传给
				//	 后台，所以后台应具体重复报文过滤功能，当“充电卡号、充电启始时间、充电结束时间”三者为一样时，可判断为同一条充电记录。
				//2．当后台查询的记录不存在时，字段 17“内部索引号”填-1，表示查询失败。
				case 402:
					log.debug("接收到cmd402指令，服务器不需要回复");
					break;

				//) 充 电 桩 回 复 服 务 器 下 发 擦 除 指 令
				case 1002:
					log.debug("接收到cmd1002回复指令，服务器不需要回复");
					break;
				//  充 电 桩 应 答 服 务 器 下 发 升 级 文 件 名 指 令
				case 1004:
					log.debug("接收到cmd1004回复指令，服务器不需要回复");
					break;
				//) 充 电 桩 应 答 服 务 器 下 发 升 级 文 件 大 小 指 令
				case 1006:
					log.debug("接收到cmd1006回复指令，服务器不需要回复");
					break;
				//) 充 电 桩 应 答 服 务 器 下 发 升 级 文 件 数 据 指 令
				case 1008:
					log.debug("接收到cmd1008回复指令，服务器不需要回复");
					break;
				// 充 电 桩 应 答 服 务 器 下 发 升 级 文 件 数 据 结 束 指 令
				case 1010:
					log.debug("接收到cmd1010回复指令，服务器不需要回复");
					break;
				//) 充 电 桩 应 答 服 务 器 下 发 重 启 指 令
				case 1012:
					log.debug("接收到cmd1012回复指令，服务器不需要回复");
					break;


				// 充 电 桩 应 答 后 台 服 务 器 查 询 24 时 电 费 计 价 策 略 信 息
				case 1102:
					log.debug("接收到cmd1102回复指令，服务器不需要回复");
					break;
				// 充 电 桩 应 答 后 台 服 务 器 设 置 24 时 电 费 计 价 策 略 信 息
				case 1104:
					log.debug("接收到cmd1104 计价策略回复指令，服务器不需要回复");
					break;
				// 充 电 桩 回 复 24 时 电 费 计 价 策 略 信 息
				case 1108:
					log.debug("接收到cmd1108回复指令，服务器不需要回复");
					break;

				//) 充 电 桩 密 码 登 入 报 文
				case 1202:
					log.debug("接收到cmd1202指令");
					Cmd1201 reply = new Cmd1201();
					reply.setCmd(1201);
					// TODO 构造返回数据
					reply.setAesSecretKey("");
					// 默认不加密
					reply.setEncryptionSign(0);
					session.write(reply);
					break;


				//  充 电 桩 应 答 白 名 单 操 作 日 志 数 据
				case 1302:
					log.debug("接收到cmd1302回复指令，服务器不需要回复");
					break;

				//) 充 电 桩 应 答 服 务 器 下 发 FTP 远 程 升 级 命 令
				case 1402:
					log.debug("接收到cmd1402回复指令，服务器不需要回复");
					break;
				//) 充 电 桩 应 答 F FT TP P  升 级 包 下 载 进 度
				case 1403:
					log.debug("接收到cmd1403回复指令，服务器不需要回复");
					break;
				//) ) 充 电 桩 应 答 服 务 器 下 发 获 取 充 电 桩 日 志 命 令
				case 1407:
					log.debug("接收到cmd1407回复指令，服务器不需要回复");
					break;

				default:
					break;
			}


			LOGGER.info("\r\ndata: {} cmd={}", "调用管理平台的接口 传递充电桩数据", protocolDataBase.getCmd());

		} catch(Exception exception) {
			LOGGER.error("业务调用 has error", exception);
		}
	}
}
